

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
//package tms;

/**
 *
 * @author Arthur
 */

public class TMS{
    private enum Machine_State {stopped, running, paused}
    private workout_settings current_settings;
    private workout_session current_session;
    private User_Profile current_profile;    
    private Machine_State machine_state;
    public safety_clip SafetyClip;
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
    }
    /* Instance Constructor */
    public TMS(){
        /*
         * Create workout_settings with default settings.
         * Create User_Profile (Guest Profile)
         * Set current session to null.
         */
        current_settings = new workout_settings();
        current_profile = new User_Profile();
        current_session = null; //current_profile.new_session();
        SafetyClip = new safety_clip();       
        machine_state = Machine_State.stopped;    
        
    }
    public void stop_workout(){
        /*
         * If machine_state is paused or running, change it to stopped.
         */
        if (machine_state == Machine_State.running || machine_state == Machine_State.paused){
            machine_state = Machine_State.stopped;
        }
    }
    public void pause_workout(){
        /*
         * If the machine_running is running, then change it
         * to paused. Otherwise, do nothing.
         */
        if (machine_state == Machine_State.running){
            machine_state = Machine_State.paused;
        }
    }
    public void start_workout(){        
         if ((machine_state == Machine_State.stopped || machine_state == Machine_State.paused) && SafetyClip.is_engaged()){
            /*
             * If the machine is paused, set machine_state to running.
             * If the machine is stopped, set machine_state to running and
             * run().
             */
            if (machine_state == Machine_State.paused){ 
                machine_state = Machine_State.running;             
            }else{
                if (machine_state == Machine_State.stopped){
                    machine_state = Machine_State.running;
                    //this.start();
                    new SessionRunner().start();
                }
            }
        }
    }
    public void user_login(String user_name, int user_pin){
        try
        {
            if (current_profile.get_logged_in() == false && machine_state == Machine_State.stopped)            
                current_profile = storage_device.get_profile(user_name, user_pin);
        }
        catch(Exception ex)
        {
            System.out.println(ex.toString());
        }
    }
    public void user_logout(){
        try
        {
            if (current_profile.get_logged_in() && machine_state == Machine_State.stopped){
                storage_device.save_profile(current_profile);
            
                //Reset current profile to Guest profile
                current_profile = new User_Profile();
            }
        }
        catch(Exception ex)
        {
            System.out.println(ex.toString());
        }
    }
    public void user_update(){
         try
        {
            if (current_profile.get_logged_in() && machine_state == Machine_State.stopped){
                storage_device.save_profile(current_profile);
                //Reset current profile to Guest profile
            }
        }
        catch(Exception ex)
        {
            System.out.println(ex.toString());
        }
    }
    public void speed_decrease(){
        /*
         * If machine_state is running, change speed and record
         * current speed (Valid only if treadmill takes on new speed
         * immediately. Refactor later).
         */
        if (machine_state == Machine_State.running){
             treadmill.decrease_current_speed();
             current_settings.set_current_speed(treadmill.get_current_speed());
        }
    }
    public void speed_increase(){
        /*
         * If machine_state is running, change speed and record
         * current speed (Valid only if treadmill takes on new speed
         * immediately. Refactor later).
         */
        if (machine_state == Machine_State.running){
             treadmill.increase_current_speed();
             current_settings.set_current_speed(treadmill.get_current_speed());
        }
    }
    public void incline_decrease(){
        /*
         * If machine_state is running, change incline and record
         * current incline (Valid only if treadmill takes on new incline
         * immediately. Refactor later).
         */
        if (machine_state == Machine_State.running){
             treadmill.decrease_current_incline();
             current_settings.set_current_speed(treadmill.get_current_incline());
        }
    }
    public void incline_increase(){
        /*
         * If machine_state is running, change incline and record
         * current incline (Valid only if treadmill takes on new incline
         * immediately. Refactor later).
         */
        if (machine_state == Machine_State.running){
             treadmill.increase_current_incline();
             current_settings.set_current_speed(treadmill.get_current_incline());
        }
    }
    /* For GUI Access */
    public String machineDisplay(){
        String outputString = "" + machine_state + ". " + SafetyClip.toString() + ".";
        outputString += "\nUser: " + current_profile.get_user_name();
        if ((machine_state == Machine_State.running || machine_state == Machine_State.paused) && current_session != null){
            java.text.NumberFormat fmt = java.text.NumberFormat.getInstance();
            fmt.setMinimumFractionDigits(4);
            outputString += "\nTime Elapsed: " + fmt.format(current_session.session_time / 60) + " Minutes";
            outputString += "\nDistance Run: " + fmt.format(current_session.distance_run) + " Miles";
            outputString += "\nDistance Climbed: " + fmt.format(current_session.distance_climbed) + " Miles";
            outputString += "\nCurrent Speed: " + fmt.format(treadmill.get_current_speed()) + " MPH";
            outputString += "\nCurrent Incline: " + fmt.format(treadmill.get_current_incline() * 180 / 3.141492) + " Degrees";
            outputString += "\nCurrent Heart Rate: " + fmt.format(current_session.heartrate_current) + " BPM";
        }        
        return outputString;
    }
    public String sessionHistory(){
        String historyString = "";
        for (int i = 0; i < current_profile.get_session_count(); i++){
            historyString += "--Session "+ (i + 1) + "--\n";
            historyString += current_profile.get_session(i)+ "\n";
        }
        return historyString;
    }
    public boolean isRunning(){
        if (machine_state != Machine_State.stopped) return true;
        else return false;
    }
    public boolean loggedIn(){
        return current_profile.get_logged_in();
    }
    public void setCurrentWeight(double value){
        if (machine_state == Machine_State.running){
            current_session.current_weight = value;
        }
    }
    
    /* To run Sessions */
    class SessionRunner extends Thread{
        public SessionRunner(){

        }
        @Override
        public void run(){
            /* Create new workout session */
            current_session = current_profile.new_session();
            /* Record Start Time*/
            double start_time = clock.get_time();
            double current_time = start_time;
            double prev_time = start_time;
            /* Start the treadmill */
            treadmill.reset();                      //Set the treadmill speed and incline to 0 MPH and 0 degrees
            treadmill.increase_current_speed();     //Set the treadmill speed to .1 MPH
            /* Conduct Workout until machine_state is set to stopped. */
            while ((machine_state == Machine_State.running || machine_state == Machine_State.paused))
            {
                prev_time = current_time;
                /* Halt Operation if paused */
                while(machine_state == Machine_State.paused ||  SafetyClip.is_engaged() == false){
                    /* Record the current time */
                    prev_time = clock.get_time();
                }
                /* Wait before next poll */
                clock.timed_wait(1);
                /* Record Elapsed Time */
                current_time = clock.get_time();
                current_session.session_time += current_time - prev_time;
                
                
                /* Update Distances */
                double dist = treadmill.get_current_speed() * (current_time - prev_time)/3600;       //Get segment distance.
                current_session.distance_run += dist;                                                   //Update total distance run.
                current_session.distance_climbed += Math.sin(treadmill.get_current_incline()) * dist;   //Update total distance climbed.

                /* Check heart rate */
                double bpm = heart_monitor.get_heart_rate();
                if (bpm > current_session.heartrate_peak) current_session.heartrate_peak = bpm;
                current_session.heartrate_current = bpm;

                
            }
        }
   
    }
}
